# -*- coding: utf-8 -*-
"""
应用显示模块
负责初始化主窗口并添加功能控件
"""

import sys
from PySide2.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QHBoxLayout, 
    QLabel, QPushButton, QFrame, QSizePolicy,QMessageBox
)
from PySide2.QtCore import Qt, QSize
from PySide2.QtGui import QPixmap, QIcon
from gglobal import logger,config
from mooetoolapp.views.mainwindows import MainWindow
from mooetoolapp.handlercore.language_manager import LanguageManager
from mooetoolapp.handlercore.bagchangeclick import BagChangeClickHandler
from mooetoolapp.handlercore.runfoxglove import RunFoxgloveHandler
from mooetoolapp.handlercore.imagesource import qInitResources


class AppShowWidget(QWidget):
    """
    应用显示控件类
    包含主要功能按钮和图标显示
    """
    
    def __init__(self, parent=None, language_manager=None):
        super(AppShowWidget, self).__init__(parent)
        # 初始化资源
        qInitResources()
        # 使用传入的语言管理器或创建新的
        self.language_manager = language_manager or LanguageManager(self)
        # 初始化Bag转换处理器
        self.bag_change_handler = BagChangeClickHandler(self)
        # 初始化Foxglove运行处理器
        self.foxglove_handler = RunFoxgloveHandler(self)
        # 车辆连接管理器引用
        self.vehicle_connection_manager = None
        # 初始化下载日志窗口引用
        self.download_log_window = None
        # 初始化车辆标定窗口引用
        self.calibration_window = None
        self.init_ui()
        
    def init_ui(self):
        """初始化用户界面"""
        # 创建主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(20)
        
        # 创建标题区域
        self.create_title_section(main_layout)
        
        # 创建功能按钮区域
        self.create_function_buttons(main_layout)
        
        # 添加弹性空间
        main_layout.addStretch()
        
        logger.info("应用显示控件初始化完成")
        
    def create_title_section(self, layout):
        """创建标题区域"""
        # 创建标题容器
        title_frame = QFrame()
        title_frame.setFrameStyle(QFrame.StyledPanel)
        title_layout = QVBoxLayout(title_frame)
        title_layout.setAlignment(Qt.AlignCenter)
        
        # 创建图标标签
        icon_label = QLabel()
        icon_label.setAlignment(Qt.AlignCenter)
        
        # 设置图标 - 使用资源文件中的图标
        try:
            icon = QIcon(":/icon/mooe.png")
            pixmap = icon.pixmap(QSize(64, 64))
            icon_label.setPixmap(pixmap)
            logger.info("图标加载成功")
        except Exception as e:
            logger.error(f"图标加载失败: {e}")
            icon_label.setText("🔧")  # 备用文本图标
            icon_label.setObjectName("backup_icon_label")
        
        # 创建标题文本
        self.title_label = QLabel()
        self.title_label.setObjectName("app_title")
        self.title_label.setAlignment(Qt.AlignCenter)
        # 注册标题文本到语言管理器
        self.language_manager.register_widget(self.title_label, "app_title")
        
        # 创建描述文本
        self.desc_label = QLabel()
        self.desc_label.setObjectName("app_description")
        self.desc_label.setAlignment(Qt.AlignCenter)
        # 注册描述文本到语言管理器
        self.language_manager.register_widget(self.desc_label, "app_description")
        
        title_layout.addWidget(icon_label)
        title_layout.addWidget(self.title_label)
        title_layout.addWidget(self.desc_label)
        
        layout.addWidget(title_frame)
        
    def create_function_buttons(self, layout):
        """创建功能按钮区域"""
        # 创建按钮容器
        buttons_frame = QFrame()
        buttons_layout = QVBoxLayout(buttons_frame)
        buttons_layout.setSpacing(15)
        
        # 定义功能按钮信息
        button_configs = [
            {
                "text": "Bag转换",
                "description": "转换ROS Bag文件格式",
                "icon": ":/icon/bagchange.svg",
                "callback": self.on_bag_convert_clicked
            },
            {
                "text": "下载日志",
                "description": "下载和管理系统日志",
                "icon": ":/icon/download.svg",
                "callback": self.on_download_log_clicked
            },
            {
                "text": "录制Bag",
                "description": "录制新的ROS Bag文件",
                "icon": ":/icon/record.svg",
                "callback": self.on_record_bag_clicked
            },
            {
                "text": "播放Bag",
                "description": "播放现有的ROS Bag文件",
                "icon": ":/icon/bagview.svg",
                "callback": self.on_play_bag_clicked
            },
            {
                "text": "车辆状态",
                "description": "查看车辆实时状态信息",
                "icon": ":/icon/vehiclestatus.svg",
                "callback": self.on_vehicle_status_clicked
            },
            {
                "text": "车辆标定",
                "description": "车辆传感器标定和参数调整",
                "icon": ":/icon/calibration.svg",
                "callback": self.on_calibration_clicked
            },
            {
                "text": "PCD查看",
                "description": "查看PCD点云文件",
                "icon": ":/icon/bagview.svg",
                "callback": self.on_pcd_view_clicked
            }
        ]
        
        # 创建功能按钮
        for i, config in enumerate(button_configs):
            button_widget = self.create_function_button(config, i)
            buttons_layout.addWidget(button_widget)
            
        layout.addWidget(buttons_frame)
        
    def create_function_button(self, config, index):
        """创建单个功能按钮"""
        # 创建按钮容器
        button_frame = QFrame()
        button_frame.setObjectName("function_button_frame")
        button_frame.setFrameStyle(QFrame.StyledPanel)
        
        # 创建水平布局
        layout = QHBoxLayout(button_frame)
        layout.setContentsMargins(15, 10, 15, 10)
        
        # 创建图标标签
        icon_label = QLabel()
        icon_label.setFixedSize(50, 50)
        icon_label.setAlignment(Qt.AlignCenter)
        
        # 处理图标 - 区分SVG图标和文本图标
        if config["icon"].startswith(":/"):
            # SVG图标
            try:
                icon = QIcon(config["icon"])
                pixmap = icon.pixmap(QSize(32, 32))
                icon_label.setPixmap(pixmap)
            except Exception as e:
                logger.error(f"SVG图标加载失败: {e}")
                icon_label.setText("📁")  # 备用文本图标
                icon_label.setObjectName("backup_icon_label")
        else:
            # 文本图标
            icon_label.setText(config["icon"])
            icon_label.setObjectName("icon_label")
        
        # 创建文本区域
        text_widget = QWidget()
        text_layout = QVBoxLayout(text_widget)
        text_layout.setContentsMargins(0, 0, 0, 0)
        text_layout.setSpacing(5)
        
        # 描述文本
        desc_label = QLabel(config["description"])
        desc_label.setObjectName("function_desc_label")
        
        # 注册描述文本到语言管理器
        desc_key = f"function_desc_{index}"
        self.language_manager.register_widget(desc_label, desc_key)
        
        text_layout.addWidget(desc_label)
        
        # 创建功能按钮
        action_button = QPushButton(config["text"])
        action_button.setObjectName("function_action_button")
        
        # 根据文本内容自适应宽度，设置最小宽度为120
        action_button.setMinimumWidth(120)
        action_button.setFixedHeight(50)
        action_button.adjustSize()  # 根据内容调整大小
        
        # 注册按钮文本到语言管理器
        button_key = f"function_button_{index}"
        self.language_manager.register_widget(action_button, button_key)
        action_button.clicked.connect(config["callback"])
        
        # 添加到布局
        layout.addWidget(icon_label)
        layout.addWidget(text_widget)
        layout.addStretch()
        layout.addWidget(action_button)
        
        return button_frame
        
    def on_bag_convert_clicked(self):
        """Bag转换按钮点击事件"""
        sender = self.sender()
        self.bag_change_handler.handle_bag_convert_clicked(sender)
    

        
    def on_download_log_clicked(self):
        """下载日志按钮点击事件"""
        logger.info("下载日志功能被点击")
        
        # 导入RemoteFileView
        from ..widget.downloadlog_view import RemoteFileView
        
        # 检查是否已经创建了下载日志窗口
        if not hasattr(self, 'download_log_window') or self.download_log_window is None:
            # 创建下载日志窗口，设置父窗口为主窗口以绑定生命周期
            main_window = self.get_main_window()
            self.download_log_window = RemoteFileView(parent=main_window)
            
            # 设置窗口标志，使其作为独立窗口显示
            self.download_log_window.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
            
            # 设置窗口标题
            window_title = self.language_manager.get_text("download_log_window_title", "下载日志 - 远程文件管理")
            self.download_log_window.setWindowTitle(window_title)
            
            # 连接语言切换信号，确保窗口标题能够更新
            self.language_manager.language_changed.connect(self.update_download_log_window_title)
            
            # 设置窗口模态性，使其与主窗口关联
            self.download_log_window.setWindowModality(Qt.ApplicationModal)
            
            # 设置窗口图标（如果有的话）
            try:
                icon = QIcon(":/icon/download.svg")
                self.download_log_window.setWindowIcon(icon)
            except Exception as e:
                logger.warning(f"设置窗口图标失败: {e}")
            
            logger.info("下载日志窗口已创建")
        
        # 显示窗口并激活
        self.download_log_window.show()
        self.download_log_window.raise_()
        self.download_log_window.activateWindow()
        
        logger.info("下载日志窗口已打开")
    
    def update_download_log_window_title(self):
        """更新下载日志窗口标题"""
        if hasattr(self, 'download_log_window') and self.download_log_window is not None:
            window_title = self.language_manager.get_text("download_log_window_title", "下载日志 - 远程文件管理")
            self.download_log_window.setWindowTitle(window_title)
    
    def get_main_window(self):
        """获取主窗口引用"""
        # 向上遍历父控件，找到MainWindow实例
        parent = self.parent()
        while parent is not None:
            if hasattr(parent, '__class__') and parent.__class__.__name__ == 'MainWindow':
                return parent
            parent = parent.parent()
        return None
        
    def on_record_bag_clicked(self):
        """录制Bag按钮点击事件"""
        logger.info("录制Bag功能被点击")
        # TODO: 实现录制Bag功能
        QMessageBox.information(
            self, 
            "录制Bag", 
            "录制Bag功能未实现"
        )
        
    def on_play_bag_clicked(self):
        """播放Bag按钮点击事件"""
        logger.info("播放Bag功能被点击")
        # 调用Foxglove处理器处理播放Bag功能
        self.foxglove_handler.handle_play_bag_clicked()

    def on_pcd_view_clicked(self):
        """PCD查看按钮点击事件"""
        logger.info("PCD查看功能被点击")
        from ..widget.pcd_viewer_widget import PCDViewerWidget
        
        # 检查窗口是否存在且有效（未被删除）
        need_create = False
        if not hasattr(self, 'pcd_viewer_window') or self.pcd_viewer_window is None:
            logger.info("PCD查看器：窗口不存在，需要创建")
            need_create = True
        else:
            # 使用try-except来安全检查窗口状态，避免访问已删除的C++对象
            try:
                if not self.pcd_viewer_window.isVisible():
                    logger.info("PCD查看器：窗口不可见，需要重新创建")
                    need_create = True
                else:
                    logger.info("PCD查看器：窗口存在且可见")
            except RuntimeError as e:
                # C++对象已被删除，需要重新创建
                logger.info("PCD查看器：C++对象已被删除，需要重新创建：%s", e)
                need_create = True
        
        if need_create:
            logger.info("PCD查看器：正在创建新窗口")
            main_window = self.get_main_window()
            self.pcd_viewer_window = PCDViewerWidget(parent=main_window)
            self.pcd_viewer_window.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
            # 设置窗口关闭时删除对象，避免C++对象已删除但Python对象仍存在的问题
            self.pcd_viewer_window.setAttribute(Qt.WA_DeleteOnClose)
            window_title = self.language_manager.get_text("pcd_viewer_window_title", "PCD 查看器")
            self.pcd_viewer_window.setWindowTitle(window_title)
            try:
                icon = QIcon(":/icon/bagview.svg")
                self.pcd_viewer_window.setWindowIcon(icon)
            except Exception:
                pass
            
            # 连接销毁信号，确保在窗口销毁时清理引用
            def on_window_destroyed():
                logger.info("PCD查看器：窗口已销毁，清理引用")
                self.pcd_viewer_window = None
            
            self.pcd_viewer_window.destroyed.connect(on_window_destroyed)
        
        logger.info("PCD查看器：显示窗口")
        self.pcd_viewer_window.show()
        self.pcd_viewer_window.raise_()
        self.pcd_viewer_window.activateWindow()
    
    def on_vehicle_status_clicked(self):
        """车辆状态按钮点击事件"""
        logger.info("车辆状态查看功能被点击")
        
        from ..widget.car_status import CarStatusWindow
        
        # 如果尚未创建窗口，则构建并配置
        if not hasattr(self, 'vehicle_status_window') or self.vehicle_status_window is None:
            main_window = self.get_main_window()
            self.vehicle_status_window = CarStatusWindow(parent=main_window, language_manager=self.language_manager)
            
            # 设置窗口标志与模态（已在窗口内部设置，此处保持风格一致）
            self.vehicle_status_window.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
            self.vehicle_status_window.setWindowModality(Qt.ApplicationModal)
            
            # 当窗口销毁时清理引用，保证可重复打开
            try:
                self.vehicle_status_window.destroyed.connect(lambda *args, **kwargs: self._on_vehicle_status_window_destroyed())
            except Exception:
                pass

            # 设置窗口标题（支持多语言）
            try:
                window_title = self.language_manager.get_text("car_status_window_title", "车辆状态")
                self.vehicle_status_window.setWindowTitle(window_title)
            except Exception:
                pass
            
            # 语言切换时更新标题
            try:
                self.language_manager.language_changed.connect(self.update_vehicle_status_window_title)
            except Exception:
                pass
            
            # 设置窗口图标
            try:
                icon = QIcon(":/icon/vehiclestatus.svg")
                self.vehicle_status_window.setWindowIcon(icon)
            except Exception:
                pass
            
            logger.info("车辆状态窗口已创建")
        
        # 显示与激活窗口
        try:
            self.vehicle_status_window.show()
            self.vehicle_status_window.raise_()
            self.vehicle_status_window.activateWindow()
        except Exception:
            pass
        
        logger.info("车辆状态窗口已打开")

    def update_vehicle_status_window_title(self):
        """更新车辆状态窗口标题"""
        if hasattr(self, 'vehicle_status_window') and self.vehicle_status_window is not None:
            window_title = self.language_manager.get_text("car_status_window_title", "车辆状态")
            self.vehicle_status_window.setWindowTitle(window_title)

    def _on_vehicle_status_window_destroyed(self):
        """窗口销毁回调：清空引用以便下次创建。"""
        try:
            self.vehicle_status_window = None
        except Exception:
            pass
    
    def on_calibration_clicked(self):
        """车辆标定按钮点击事件"""
        logger.info("车辆标定功能被点击")
        
        # 导入CalibrationWidget
        from ..widget.calibration_widget import CalibrationWidget
        
        # 检查是否已经创建了标定窗口
        if not hasattr(self, 'calibration_window') or self.calibration_window is None:
            # 创建标定窗口，设置父窗口为主窗口以绑定生命周期
            main_window = self.get_main_window()
            self.calibration_window = CalibrationWidget(parent=main_window, language_manager=self.language_manager)
            
            # 设置窗口标志，使其作为独立窗口显示
            self.calibration_window.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint | Qt.WindowMinMaxButtonsHint)
            
            # 设置窗口标题
            window_title = self.language_manager.get_text("calibration_window_title", "车辆标定")
            self.calibration_window.setWindowTitle(window_title)
            
            # 连接语言切换信号，确保窗口标题能够更新
            self.language_manager.language_changed.connect(self.update_calibration_window_title)
            
            # 设置窗口模态性，使其与主窗口关联
            self.calibration_window.setWindowModality(Qt.ApplicationModal)
            
            # 设置窗口大小
            self.calibration_window.resize(1200, 800)
            
            # 设置窗口图标（如果有的话）
            try:
                icon = QIcon(":/icon/calibration.svg")
                self.calibration_window.setWindowIcon(icon)
            except Exception as e:
                logger.warning(f"设置窗口图标失败: {e}")
            
            logger.info("车辆标定窗口已创建")
        
        # 显示窗口并激活
        self.calibration_window.show()
        self.calibration_window.raise_()
        self.calibration_window.activateWindow()
        
        logger.info("车辆标定窗口已打开")
    
    def update_calibration_window_title(self):
        """更新标定窗口标题"""
        if hasattr(self, 'calibration_window') and self.calibration_window is not None:
            window_title = self.language_manager.get_text("calibration_window_title", "车辆标定")
            self.calibration_window.setWindowTitle(window_title)

    def closeEvent(self, event):
        """窗口关闭事件"""
        # 清理Bag转换处理器资源
        if hasattr(self, 'bag_change_handler'):
            self.bag_change_handler.cleanup()
        # 清理Foxglove处理器资源
        if hasattr(self, 'foxglove_handler'):
            self.foxglove_handler.cleanup()
        # 清理下载日志窗口
        if hasattr(self, 'download_log_window') and self.download_log_window is not None:
            self.download_log_window.close()
            self.download_log_window = None
        # 清理车辆标定窗口
        if hasattr(self, 'calibration_window') and self.calibration_window is not None:
            self.calibration_window.close()
            self.calibration_window = None
        # 清理PCD查看窗口
        if hasattr(self, 'pcd_viewer_window') and self.pcd_viewer_window is not None:
            self.pcd_viewer_window.close()
            self.pcd_viewer_window = None
        super().closeEvent(event)
    
    def cleanup(self):
        """清理资源"""
        if hasattr(self, 'bag_change_handler'):
            self.bag_change_handler.cleanup()
        if hasattr(self, 'foxglove_handler'):
            self.foxglove_handler.cleanup()
        # 清理下载日志窗口
        if hasattr(self, 'download_log_window') and self.download_log_window is not None:
            self.download_log_window.close()
            self.download_log_window = None
        # 清理车辆标定窗口
        if hasattr(self, 'calibration_window') and self.calibration_window is not None:
            self.calibration_window.close()
            self.calibration_window = None
        # 清理车辆状态窗口
        if hasattr(self, 'vehicle_status_window') and self.vehicle_status_window is not None:
            try:
                self.vehicle_status_window.close()
            except Exception:
                pass
            self.vehicle_status_window = None
        # 清理PCD查看窗口
        if hasattr(self, 'pcd_viewer_window') and self.pcd_viewer_window is not None:
            try:
                self.pcd_viewer_window.close()
            except Exception:
                pass
            self.pcd_viewer_window = None


class AppShow:
    """
    应用显示主类
    负责初始化主窗口并添加功能控件
    """
    
    def __init__(self):
        self.main_window = None
        self.app_widget = None
        
    def initialize(self):
        """初始化应用显示"""
        try:
            # 创建主窗口
            self.main_window = MainWindow()
            
            # 创建应用显示控件，传入主窗口的语言管理器
            self.app_widget = AppShowWidget(parent=self.main_window, language_manager=self.main_window.language_manager)
            
            # 将控件添加到主窗口的垂直布局中
            main_layout = self.main_window.get_main_layout()
            main_layout.addWidget(self.app_widget)
            
            logger.info("应用显示初始化完成")
            return self.main_window
            
        except Exception as e:
            logger.error(f"应用显示初始化失败: {e}")
            raise
            
    def show(self):
        """显示主窗口"""
        if self.main_window:
            self.main_window.show()
            
    def get_main_window(self):
        """获取主窗口实例"""
        return self.main_window


if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 创建应用显示
    app_show = AppShow()
    main_window = app_show.initialize()
    app_show.show()
    
    sys.exit(app.exec_())
